package sam.jmsgserver.core;

import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.FileHandler;
import java.util.logging.Logger;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;

public class Server {

	private static ArrayBlockingQueue<Runnable> taskQueue = new ArrayBlockingQueue<Runnable>(1000);
	private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, taskQueue);
	public static Connection connection = null;
	
	public static Logger logger = Logger.getAnonymousLogger();
	
	public static void main(String[] agrs){
		Server.logger.info("Starting Server...");
		
		Server.logger.info("groupchat="+Message.Type.groupchat);
		
		configLogger();
		
		ConnectionConfiguration config = new ConnectionConfiguration(Config.XMPP_HOST, Config.XMPP_PORT, Config.XMPP_SERVICE);
		config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
		connection = new XMPPConnection(config);
		try {
			connection.connect();
			connection.login(Config.GMAIL_LOGIN, Config.GMAIL_PASSWORD);
			
			final MessageListener msgListener = new MessageListener() {

			    public void processMessage(Chat chat, Message message) {
			    	Server.logger.info("Msg Type:"+message.getType());
			    	
			    	if (Message.Type.chat.equals(message.getType())){
			    		SendMsgTask sendMsgTask = new SendMsgTask();
				        sendMsgTask.setMsg(message);
				        sendMsgTask.setConnection(connection);
				        threadPoolExecutor.execute(sendMsgTask);
			    	}
			    	else if (Message.Type.error.equals(message.getType())){
			    		ErrorMsgTask errorMsgTask = new ErrorMsgTask();
				        errorMsgTask.setMsg(message);
				        errorMsgTask.setConnection(connection);
				        threadPoolExecutor.execute(errorMsgTask);
			    	}
			        
			    }
			};
			
			connection.getChatManager().addChatListener(new ChatManagerListener(){
				public void chatCreated(Chat chat, boolean createdLocally){
					chat.addMessageListener(msgListener);
				}
			});
			
//			for (RosterEntry entry : connection.getRoster().getEntries()){
//				System.out.println("user:"+entry.getUser());
//			}
			
			while(true){
				try {
					Thread.sleep(60000);
				} catch (InterruptedException e) {
				}
			}
			
			
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		finally{
			try{connection.disconnect();}catch(Exception ignored){}
		}
	}
	
	private static void configLogger(){
		try {
			logger.addHandler(new FileHandler(Config.LOG_FILE));
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
